// Copyright 2010 Google Inc.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//      http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <string>
#include <vector>
#include <utility>

#include "public/hash_map.h"

#include "public/porting.h"
#include "public/commandlineflags.h"


// Also does post-static-initialization global initialization.

void ProcessCommandLineArguments(int& argc, char**& argv) {
 google::ParseCommandLineFlags(&argc, &argv, true);
}


// ----------------------------------------------------------------------------
// Handling of post-static-initialization startup code.


// Do not rely on static initialization for setting up init_list,
// since elements are added to it during static initialization.
static vector<pair<const char*,void(*)()> >* init_list = NULL;


int RegisterModuleInitializer(const char* name, void (*init)()) {
  if (init_list == NULL)
    init_list = new vector<pair<const char*,void(*)()> >;
  init_list->push_back(pair<const char*,void(*)()>(name, init));
  return 0;
}


void InitializeOneModule(const char* name) {
  if (init_list != NULL) {
    for (int i = 0; i < init_list->size(); i++) {
      if (strcmp((*init_list)[i].first, name) == 0 &&
          (*init_list)[i].second != NULL) {
        void (*f)() = (*init_list)[i].second;
        (*init_list)[i].second = NULL;
        (*f)();
      }
    }
  }
}


void InitializeAllModules() {
  if (init_list != NULL) {
    for (int i = 0; i < init_list->size(); i++) {
      if ((*init_list)[i].second != NULL) {
        (*(*init_list)[i].second)();
        (*init_list)[i].second = NULL;
      }
    }
  }
}
